package com.woniu.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.woniu.entity.*;
import com.woniu.service.CollectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.CharSequenceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Api(value = "催收控制器", tags = {"催收"})
@RestController
@RequestMapping("/collect")
public class CollectController extends BaseController {
    @Autowired
    CollectService collectService;

    @ApiOperation(value = "查询所有催收订单",notes = "根据订单状态查询所有催收订单",
            response=CollectionListVO.class, responseContainer="List", httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @GetMapping("/listCollections")
    public TableDataInfo listCollections()
    {
        startPage();
        List<CollectionListVO> list = collectService.listCollections();
        return getDataTable(list);
    }

    @ApiOperation(value = "查询所有催收订单",notes = "根据订单状态查询所有催收订单",
            response=AjaxResult.class, httpMethod="POST",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "data",value="订单状态需要的参数",required=true,dataTypeClass=Map.class,paramType="body"))
    @ResponseBody
    @PostMapping("/saveCollectRecord")
    public AjaxResult saveCollectRecord(@RequestBody Map<String,Object> data)
    {
        Integer res = collectService.saveCollectRecord(data);
        System.out.println("查询结果"+res);
        if (res>0){
            return new AjaxResult(HttpStatus.SUCCESS,"保存催收记录成功",null);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "添加催收记录",notes = "根据传入参数添加催收记录",
            response=AjaxResult.class, httpMethod="POST",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "data",value="催收记录需要的参数",required=true,dataTypeClass=Map.class,paramType="body"))
    @ResponseBody
    @PostMapping("/addCollectRecord")
    public AjaxResult addCollectRecord(@RequestBody Map<String,Object> data)
    {
        Integer res = collectService.addCollectRecord(data);
        System.out.println("查询结果"+res);
        if (res>0){
            return new AjaxResult(HttpStatus.SUCCESS,"保存催收记录成功",null);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "更新客户评论",notes = "根据传入参数添加单个客户评论",
            response=AjaxResult.class, httpMethod="POST",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "data",value="客户评论需要的参数",required=true,dataTypeClass=Map.class,paramType="body"))
    @ResponseBody
    @PostMapping("/updateClientRemark")
    public AjaxResult updateClientRemark(@RequestBody Map<String,Object> data)
    {
        Integer res = collectService.updateClientRemark(data);
        System.out.println("查询结果"+res);
        if (res>0){
            return new AjaxResult(HttpStatus.SUCCESS,"修改用户备注成功",null);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }


    @ApiOperation(value = "查询催收记录",notes = "根据传入参数查询催收记录的集合",
            response=AjaxResult.class, httpMethod="POST",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "data",value="查询催收记录需要的参数",required=true,dataTypeClass=SearchCollectVO.class,paramType="body"))
    @ResponseBody
    @PostMapping("/searchCollectList")
    public AjaxResult searchCollectList(@RequestBody SearchCollectVO data)
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (Objects.nonNull(data.getWriteTime()) && data.getWriteTime().size()!=0){
            for (int i = 0; i < data.getWriteTime().size(); i++) {
                String temp = format.format(data.getWriteTime().get(i));

                if (i==0){
                    data.getWriteTimeMap().put("startTime",temp);
                }else{
                    data.getWriteTimeMap().put("endTime",temp);
                }
            }
        }

        if(Objects.nonNull(data.getCollectFinishTime()) && data.getCollectFinishTime().size()!=0){
            for (int i = 0; i < data.getCollectFinishTime().size(); i++) {
                String temp = format.format(data.getCollectFinishTime().get(i));

                if (i==0){
                    data.getCollectFinishTimeMap().put("startTime",temp);
                }else{
                    data.getCollectFinishTimeMap().put("endTime",temp);
                }
            }
        }




        System.out.println("查询参数"+data);
        List<CollectionListVO> res = collectService.searchCollectList(data);
        System.out.println("查询结果"+res);
        if (Objects.nonNull(res) && res.size()>0){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取客户信息",notes = "根据传入贷款订单id查询客户信息",
            response=AjaxResult.class, httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "loanInfoId",value="贷款订单id",required=true,dataTypeClass=Integer.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getClientInfo/{loanInfoId}")
    public AjaxResult getClientInfo(@PathVariable("loanInfoId") Integer loanInfoId)
    {
        Client res = collectService.getClientInfo(loanInfoId);
        if (Objects.nonNull(res)){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取操作员信息",notes = "根据传入姓名查询操作员信息",
            response=AjaxResult.class, httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "name",value="操作员姓名",required=true,dataTypeClass=String.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getOperatorInfo/{name}")
    public AjaxResult getOperatorInfo(@PathVariable("name") String name)
    {
        SysAdminVO res = collectService.getOperatorInfo(name);
        System.out.println("当前用户信息"+res);
        if (Objects.nonNull(res)){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取催收详情信息",notes = "根据传入催收订单id查询催收详情信息",
            response=AjaxResult.class, httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "billId",value="催收订单id",required=true,dataTypeClass=Integer.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getBillDetail/{billId}")
    public AjaxResult getBillDetail(@PathVariable("billId") Integer billId)
    {
        BillDetailVO res = collectService.getBillDetail(billId);
        if (Objects.nonNull(res)){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取贷款订单信息",notes = "根据传入贷款订单id查询贷款订单信息",
            response=AjaxResult.class, httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "loanInfoId",value="贷款订单id",required=true,dataTypeClass=Integer.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getBillOrders/{billId}")
    public AjaxResult getBillOrders(@PathVariable("billId") Integer loanInfoId)
    {
        List<BillDetailVO> res = collectService.getBillOrders(loanInfoId);
        if (Objects.nonNull(res)&&res.size()!=0){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取催收订单列表信息",notes = "根据传入贷款订单id查询催收订单列表信息",
            response=AjaxResult.class, responseContainer="List", httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "loanInfoId",value="贷款订单id",required=true,dataTypeClass=Integer.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getBillListInfo/{loanInfoId}")
    public AjaxResult getBillListInfo(@PathVariable("loanInfoId") Integer loanInfoId)
    {
        List<BillListInfoVO> res = collectService.getBillListInfo(loanInfoId);
        System.out.println("催收列表查询结果"+res);
        calBillParams(res);
        System.out.println(res);
        if (Objects.nonNull(res)&&res.size()!=0){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",res);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取字典信息",notes = "根据传入字典名称获取字典信息",
            response=AjaxResult.class, responseContainer="List", httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "name",value="字典名称",required=true,dataTypeClass=String.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getDictKeyInfo/{name}")
    public AjaxResult getDictKeyInfo(@PathVariable("name") String name)
    {
        List<SysDictData> dictCache = DictUtils.getDictCache(name);
        if (Objects.nonNull(dictCache)&&dictCache.size()!=0){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",dictCache);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }

    @ApiOperation(value = "获取产品信息",notes = "根据传入贷款订单id获取产品信息",
            response=AjaxResult.class, httpMethod="GET",
            produces="application/json",code=200,tags = {"催收"})
    @ApiImplicitParams(@ApiImplicitParam(name = "loanInfoId",value="贷款订单id",required=true,dataTypeClass=Integer.class,paramType="path"))
    @ResponseBody
    @GetMapping("/getProductionInfo/{loanInfoId}")
    public AjaxResult getProductionInfo(@PathVariable("loanInfoId") Integer loanInfoId)
    {
       Production production = collectService.getProductionInfo(loanInfoId);
        if (Objects.nonNull(production)){
            return new AjaxResult(HttpStatus.SUCCESS,"查询成功",production);
        }else{
            return new AjaxResult(HttpStatus.ERROR,"操作失败，请稍后再试",null);
        }
    }


    @ApiOperation(value = "导出催收信息",notes = "根据用户选择的对应行导出所有催收信息",
            response=void.class, httpMethod="POST",
            produces="application/json",code=200,tags = {"催收"})
    @PostMapping("/exportChosen")
    @ResponseBody
    public void export(HttpServletResponse response, UsualExportVO data){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<CollectionListVO> list = collectService.selectCollectionList(data);
        list.forEach((e)->{
            e.setCollectorName(e.getCollector().getNickName());
            try {
                e.setAppointCollectionTime(formatter.format(formatter.parse(e.getAppointCollectionTime())));
            } catch (ParseException ex) {
                ex.printStackTrace();
            }
        });
        ExcelUtil<CollectionListVO> util = new ExcelUtil<> (CollectionListVO.class);
        util.exportExcel(response,list,KeyWords.EXPORT_COLLECT_LIST_NAME);
    }

    /**
     * @description: 计算催收订单应还款的期数、罚息、截止日期
     * @param: [res]
     * @return: void
     * @author Dante
     * @date: 2022/10/7 17:33
     */
    public void calBillParams(List<BillListInfoVO> res){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss");
        for (int i = 0; i < res.size(); i++) {
            Integer periods = res.get(i).getPeriods();
            if (periods%12==0){
                int factor = periods/12;
                LocalDateTime temp = LocalDateTime.parse(res.get(i).getCreditTime(), formatter);
                LocalDateTime deadline = LocalDateTime.parse(res.get(i).getEssentialPayDeadline(), formatter);
                LocalDateTime writeTime = LocalDateTime.parse(res.get(i).getWriteTime(), formatter);
                LocalDateTime origin = temp.plusYears(factor);
                if(origin.getMonth().plus(i)==deadline.getMonth()){
                    res.get(i).setPeriods(i+1);
                    int dayOfWriteTime = writeTime.getDayOfMonth();
                    int dayOfDeadline = deadline.getDayOfMonth();
                    if(dayOfWriteTime!=dayOfDeadline && dayOfWriteTime>dayOfDeadline){
                        NumberFormat numberFormat = NumberFormat.getNumberInstance();
                        numberFormat.setMaximumFractionDigits(3);
                        res.get(i).setDelayDays((dayOfWriteTime-dayOfDeadline));
                        double v = res.get(i).getDelayPaybackRatio() * res.get(i).getEssentialPayment();
                        res.get(i).setDelayPaybackMoney(Double.valueOf(numberFormat.format(v)));
                    }
                }
            }else {
                int factor = periods%12;
                LocalDateTime temp = LocalDateTime.parse(res.get(i).getCreditTime(), formatter);
                LocalDateTime deadline = LocalDateTime.parse(res.get(i).getEssentialPayDeadline(), formatter);
                LocalDateTime writeTime = LocalDateTime.parse(res.get(i).getWriteTime(), formatter);
                LocalDateTime origin = temp.plusMonths(factor);

                if(origin.getMonth().plus(i)==deadline.getMonth()){
                    res.get(i).setPeriods(i+1);
                    int dayOfWriteTime = writeTime.getDayOfMonth();
                    int dayOfDeadline = deadline.getDayOfMonth();
                    if(dayOfWriteTime!=dayOfDeadline && dayOfWriteTime>dayOfDeadline){
                        NumberFormat numberFormat = NumberFormat.getNumberInstance();
                        numberFormat.setMaximumFractionDigits(3);
                        res.get(i).setDelayDays((dayOfWriteTime-dayOfDeadline));
                        double v = res.get(i).getDelayPaybackRatio() * res.get(i).getEssentialPayment();
                        res.get(i).setDelayPaybackMoney(Double.valueOf(numberFormat.format(v)));
                    }
                }
            }

        }
    }
}
